package com.itheima.ai.config;

import com.itheima.ai.tool.CourseTool;
import com.itheima.ai.constants.SystemConstants;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepository;
import org.springframework.ai.chat.memory.repository.jdbc.MysqlChatMemoryRepositoryDialect;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiEmbeddingModel;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.filter.CharacterEncodingFilter;

import java.nio.charset.StandardCharsets;

/**
 * 配置类
 *
 * @Author mr.wu
 * @Date 2025-11-4 9:45
 */
@Configuration
public class CommonConfig {


    /**
     * 声明SpringAI对话实例 - 聊天机器人使用
     * @param ollamaChatModel
     * @return
     */
    @Bean
    public ChatClient chatClient(OllamaChatModel ollamaChatModel, ChatMemory chatMemory) {
        return ChatClient.builder(ollamaChatModel)
                .defaultSystem("您是一家名为“黑马程序员”的职业教育公司的客户聊天助手，你的名字叫小黑。请以友好、乐于助人和愉快的方式解答学生的各种问题。")//系统角色和背景任务
                .defaultAdvisors(new SimpleLoggerAdvisor())//添加日志增强器（大模型调用前后都会记录日志）
                .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()) //添加对话记忆增强器
                .build();//构建对话实例
    }

    /**
     * 声明SpringAI对话实例 - 黑马智能客服使用
     * @param openAiChatModel
     * @return
     */
    @Bean
    public ChatClient chatServiceClient(OpenAiChatModel openAiChatModel, ChatMemory chatMemory, CourseTool courseTool) {
        return ChatClient.builder(openAiChatModel)
                .defaultSystem(SystemConstants.CUSTOMER_SERVICE_SYSTEM)//系统角色和背景任务
                .defaultAdvisors(new SimpleLoggerAdvisor())//添加日志增强器（大模型调用前后都会记录日志）
                .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()) //添加对话记忆增强器
                .defaultTools(courseTool)//注册课程工具（智能客服的FunctionCalling技术方案会用到）
                .build();//构建对话实例
    }

    /**
     * 声明SpringAI对话实例 - RAG知识库使用
     * @param openAiChatModel
     * @return
     */
    @Bean
    public ChatClient chatPdfClient(OpenAiChatModel openAiChatModel, ChatMemory chatMemory, VectorStore vectorStore) {
        return ChatClient.builder(openAiChatModel)
                .defaultSystem("主要以知识库为准去回答，不要随便猜测")//系统角色和背景任务
                .defaultAdvisors(new SimpleLoggerAdvisor())//添加日志增强器（大模型调用前后都会记录日志）
                .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()) //添加对话记忆增强器
                .defaultAdvisors(QuestionAnswerAdvisor.builder(vectorStore)
                        .searchRequest(SearchRequest.builder()
                                .topK(3)//保留相似度最高的几条
                                .similarityThreshold(0.5)//余弦相识度（余弦距离的值）
                                .build())
                        .build())
                .build();//构建对话实例
    }

    /**
     * 声明会话记忆持久层存储实例
     * @param jdbcTemplate
     * @return
     */
    @Bean
    public ChatMemoryRepository chatMemoryRepository(JdbcTemplate jdbcTemplate) {
        ChatMemoryRepository chatMemoryRepository = JdbcChatMemoryRepository.builder()
                .jdbcTemplate(jdbcTemplate)
                .dialect(new MysqlChatMemoryRepositoryDialect())
                .build();
        return chatMemoryRepository;
    }

    /**
     * 声明字符编码过滤器
     * @return
     */
    @Bean
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setForceEncoding(true);//强制
        characterEncodingFilter.setEncoding(StandardCharsets.UTF_8.name());//utf-8国际通用编码
        return characterEncodingFilter;
    }

    /**
     * 声明向量数据库实例，默认用SimpleVectorStore
     * @param openAiEmbeddingModel  向量模型实例
     * @return
     */
    @Bean
    public VectorStore vectorStore(OpenAiEmbeddingModel openAiEmbeddingModel) {
        return SimpleVectorStore.builder(openAiEmbeddingModel).build();
    }
}
